/**
 * 初始化索引
 * @param {*} db
 * @param {*} indexConfig
 * @param {Object} [config=]
 * @param {boolean} [config.dropNotExist=false] - 是否删除多余的索引
 * @return {Promise<Object>}
 */
async function initIndexes (db, indexConfig, config) {
  config = {
    ...{ dropNotExist: false },
    ...(config || {})
  }

  const isIndexEqual = (index1, index2) => {
    if (index1.weights) {
      const keyName = Object.keys(index2.key).map(key => {
        return `${key}_${index2.key[key]}`
      }).join('_')
      return index1.name === keyName
    }
    return JSON.stringify(index1.key) === JSON.stringify(index2.key)
  }

  return await Promise.all(Object.keys(indexConfig).map(async collectionName => {
    const collection = indexConfig[collectionName]
    let currentIndexes = await db.collection(collectionName).indexes()
    currentIndexes = currentIndexes.filter(e => e.name !== '_id_')
    const expectIndexes = collection.indexes.filter(e => Object.keys(e.key).length > 0)
    const alreadyExistIndexes = expectIndexes.filter(expectIndex => {
      return currentIndexes.find(currentIndex => isIndexEqual(currentIndex, expectIndex))
    })
    // 删除无用的索引
    let dropIndexResults = []
    if (config.dropNotExist) {
      const unexpectIndexes = currentIndexes.filter(currentIndex => {
        return !expectIndexes.find(expectIndex => isIndexEqual(currentIndex, expectIndex))
      })
      dropIndexResults = await Promise.all(unexpectIndexes.map(async index => {
        return await db.collection(collectionName).dropIndex(index.name)
      }))
    }
    // 新增必要索引
    const needCreateIndexes = expectIndexes.filter(expectIndex => {
      return !currentIndexes.find(currentIndex => isIndexEqual(currentIndex, expectIndex))
    })
    const createIndexResults = await Promise.all(needCreateIndexes.map(async index => {
      return await db.collection(collectionName).createIndex(index.key, {
        ...{ background: true },
        ...index.options
      })
    }))
    return {
      collectionName,
      alreadyExistIndexes,
      createIndexResults,
      dropIndexResults
    }
  }))
}

module.exports = { initIndexes }
